package com.dmc.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dmc.conf.Constant;
import com.dmc.dict.BenefitTranTypeDict;
import com.dmc.dict.IntegralTranTypeDict;
import com.dmc.entity.Message;
import com.dmc.mapper.*;
import com.dmc.model.BenefitTransaction;
import com.dmc.model.DistributionOrder;
import com.dmc.model.IntegralTransaction;
import com.dmc.model.TUserAccount;
import com.dmc.service.UserAccountService;
import com.dmc.util.DecimalUtil;
import com.dmc.util.Sha512;
import com.dmc.util.util.SessionUtil;
import com.dmc.util.util.StringUtil;
import com.dmc.vo.DataTable;
import com.dmc.vo.IntegralDetailVo;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.jacoco.agent.rt.internal_43f5073.core.internal.flow.IFrame;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

@Service("userAccountService")
@Transactional
public class UserAccountServiceImpl implements UserAccountService {

    @Resource
    private TUserAccountMapper tUserAccountMapper;
    @Resource
    private IntegralTransactionMapper integralTransactionMapper;
    @Resource
    private MessageMapper messageMapper;
    @Autowired
    private DistributionOrderMapper distributionOrderMapper;

    @Autowired
    private BenefitTransactionMapper benefitTransactionMapper;

    /**
     * 保存用户账户信息
     * @param userAccount
     * @return
     */
    @Override
    public void save(TUserAccount userAccount) {
        Long userId = userAccount.getUserId();
        Assert.notNull(userId,"新增用户账户失败,无USERID");
        Map<String,Object> param = new HashMap<>();
        param.put("user_id",userId);
        List<TUserAccount> tUserAccounts = tUserAccountMapper.selectByMap(param);
        Assert.isTrue(CollectionUtil.isEmpty(tUserAccounts),"新增用户账户失败,当前用户已有账户");
        tUserAccountMapper.insert(userAccount);
    }
    /**
     * 初始化账户信息
     * @param userId
     * @return
     */
    @Override
    public TUserAccount initUserAccountByUserId(Long userId){
        TUserAccount tUserAccount=tUserAccountMapper.selectUserAccountByUserId(userId);
        if(tUserAccount == null){
            tUserAccount = new TUserAccount();
            tUserAccount.setUserId(userId);
            tUserAccount.setBenefit(BigDecimal.ZERO);
            tUserAccount.setIntegral(BigDecimal.ZERO);
            tUserAccount.setCreateTime(new Date());
            tUserAccount.setIntegralReturn(BigDecimal.ZERO);
            save(tUserAccount);
        }
        return tUserAccount;
    }

    /**
     * 更新用户积分
     * @param userId
     * @param integral
     */
    @Override
    public void updateUserAccount(Long userId, BigDecimal integral){
        tUserAccountMapper.updateUserAccount(userId,integral);
    }

    /**
     * 根据用户获取用户积分使用记录
     * @param userId
     * @return
     */
    @Override
    public List<IntegralTransaction> getUserIntegralList(Long userId){
        return integralTransactionMapper.selectUserIntegralList(userId);
    }

    /**
     * 获取全部积分明细
     * @param
     * @return
     */
    @Override
    public DataTable<IntegralDetailVo> getUserIntegralDetailList(IntegralDetailVo vo){
        Integer start = vo.getStart();
        if(start == null){
            vo.setStart(0);
        }
        Integer length = vo.getLength();
        if(length == null){
            vo.setLength(10);
        }
        PageHelper.startPage(vo.getStart(), vo.getLength());
        String userName = vo.getUserName();
        if(StringUtils.isNotBlank(userName)){
            userName = "%"+userName.trim()+"%";
            vo.setUserName(userName);
        }
        String userPhone = vo.getUserPhone();
        if(StringUtils.isNotBlank(userPhone)){
            userPhone = "%"+userPhone.trim()+"%";
            vo.setUserPhone(userPhone);
        }
        String orderNo = vo.getOrderNo();
        if(StringUtils.isNotBlank(orderNo)){
            orderNo = "%"+orderNo.trim()+"%";
            vo.setOrderNo(orderNo);
        }
        //搜索条件
        List<IntegralDetailVo> integralDetailVoList=integralTransactionMapper.selectIntegralDetailList(vo);
        for (IntegralDetailVo data:integralDetailVoList){
            if(data.getType()== IntegralTranTypeDict.NTEGRAL_TRAN_TYPE_GOODS.getCn()){
                data.setTypeName(IntegralTranTypeDict.getDescByCn(IntegralTranTypeDict.NTEGRAL_TRAN_TYPE_GOODS.getCn()));
            }else if(data.getType()==IntegralTranTypeDict.INTEGRAL_TRAN_TYPE_DISTRUBUTION.getCn()){
                Long orderId = data.getOrderId();
                DistributionOrder distributionOrder = distributionOrderMapper.selectById(orderId);
                if(distributionOrder!=null){
                    data.setOrderNo(distributionOrder.getOrderNo());
                }
                data.setTypeName(IntegralTranTypeDict.getDescByCn(IntegralTranTypeDict.INTEGRAL_TRAN_TYPE_DISTRUBUTION.getCn()));
            }else if(data.getType()==IntegralTranTypeDict.NTEGRAL_TRAN_TYPE_GOODS_300.getCn()){
                data.setTypeName(IntegralTranTypeDict.getDescByCn(IntegralTranTypeDict.NTEGRAL_TRAN_TYPE_GOODS_300.getCn()));
            }
        }
        DataTable<IntegralDetailVo> tables = new DataTable<>();
        tables.setRecordsTotal(((Page) integralDetailVoList).getTotal());
        tables.setRecordsFiltered(tables.getRecordsTotal());
        tables.setDraw(vo.getDraw());
        tables.setData(integralDetailVoList);
        return tables;
    }

    /**
     * 我的消息
     * @param userId
     * @return
     */
    @Override
    public List<Message> getUserMessage(Long userId){
        Map<String,Object> param = new HashMap<>();
        param.put("user_id",userId);
        List<Message> messageList=messageMapper.selectByMap(param);
        if(!CollectionUtils.isEmpty(messageList)){
            //把用户未读消息置为已读
            for (Message message:messageList){
                if(message.getStatus()==0){
                    message.setStatus(1);
                    message.setUpdateTime(new Date());
                    messageMapper.updateById(message);
                }
            }
        }
        return messageList;
    }

    /**
     * 添加用户消息,0:订单发货 1:分销商升级添加消息
     * @param message
     * @return
     */
    @Override
    public Integer addUserMessage(Message message){
        Date now=new Date();
        message.setCreateTime(now);
        message.setUpdateTime(now);
        message.setStatus(0);
        return messageMapper.insertAllColumn(message);
    }

    @Override
    public void addBenefitTransaction(BenefitTransaction bt) {
        bt.setCreateTime(new Date());
        //获取此类型当前收益总额
        List<Integer> typeList = new ArrayList<>();
        typeList.add(bt.getType());
        BigDecimal sumType = benefitTransactionMapper.getSumByTypeList(bt.getUserId(),typeList);
        bt.setCurrentTypeBenefit(DecimalUtil.addArray(bt.getBenefit(),sumType));
        benefitTransactionMapper.insert(bt);
    }

    @Override
    public void checkPayPassword(Long userId, String password) {
        TUserAccount tUserAccount = initUserAccountByUserId(userId);
        String payPassword = tUserAccount.getPayPassword();
        Assert.isTrue(StringUtils.isNotBlank(payPassword),"此用户尚未设置密码");
        String in = password + Sha512.payPasswordSalt;
        in = Sha512.getSha512(in);
        Assert.isTrue(in.equals(payPassword),"密码错误");
    }

    @Override
    public void addPayPassword(Long userId, String password) {
        TUserAccount tUserAccount = initUserAccountByUserId(userId);
        String payPassword = tUserAccount.getPayPassword();
        Assert.isTrue(StringUtils.isBlank(payPassword),"此用户已有密码,无法添加");
        password = password + Sha512.payPasswordSalt;
        password  = Sha512.getSha512(password);
        tUserAccount.setPayPassword(password);
        tUserAccountMapper.updateById(tUserAccount);
    }

    @Override
    public void updatePayPassword(Long userId, String password, String passwordOld) {
        //校验旧密码
        checkPayPassword(userId,passwordOld);
        TUserAccount tUserAccount = initUserAccountByUserId(userId);
        password = password + Sha512.payPasswordSalt;
        password  = Sha512.getSha512(password);
        tUserAccount.setPayPassword(password);
        tUserAccountMapper.updateById(tUserAccount);
    }

    @Override
    public Boolean checkHavePayPassword(Long userId) {
        userId = SessionUtil.getCurrUid();
        TUserAccount tUserAccount = initUserAccountByUserId(userId);
        return StringUtil.isNotEmpty(tUserAccount.getPayPassword());
    }

    @Override
    public void addIntegralTransaction(IntegralTransaction integralTransaction) {
        integralTransactionMapper.insert(integralTransaction);
    }

    @Override
    public void integralReturn(BigDecimal userIntegral,Long userId,String configValue) {
        //积分返现处理
        if(StringUtil.isEmpty(configValue)){
            return;
        }
        TUserAccount tUserAccount = initUserAccountByUserId(userId);
        BigDecimal integralReturn = tUserAccount.getIntegralReturn();
        integralReturn = DecimalUtil.addArray(integralReturn,userIntegral);
        JSONObject jiFenReturnConfig = JSON.parseObject(configValue);
        BigDecimal payIntegralLimit = jiFenReturnConfig.getBigDecimal("payIntegralLimit");
        tUserAccount.setIntegralReturn(integralReturn);
        tUserAccountMapper.updateById(tUserAccount);
        while(integralReturn.compareTo(payIntegralLimit)>=0){
            integralReturn = integralReturn( userId, jiFenReturnConfig);
        }
        tUserAccount = initUserAccountByUserId(userId);
        tUserAccount.setIntegralReturn(integralReturn);
        tUserAccountMapper.updateById(tUserAccount);
    }

    @Override
    public void updatePayPasswordForPc(Long userId, String payPassWord) {
        TUserAccount tUserAccount = initUserAccountByUserId(userId);
        payPassWord = payPassWord + Sha512.payPasswordSalt;
        payPassWord  = Sha512.getSha512(payPassWord);
        tUserAccount.setPayPassword(payPassWord);
        tUserAccountMapper.updateById(tUserAccount);
    }

    private BigDecimal integralReturn(Long userId,JSONObject jiFenReturnConfig){
        BigDecimal payIntegralLimit = jiFenReturnConfig.getBigDecimal("payIntegralLimit");
        TUserAccount tUserAccount = initUserAccountByUserId(userId);
        BigDecimal integralReturn = tUserAccount.getIntegralReturn();
        integralReturn = DecimalUtil.subArrayOriginalValue(integralReturn,payIntegralLimit);
        tUserAccount.setIntegralReturn(integralReturn);
        //返现金
        BigDecimal benefit = tUserAccount.getBenefit();
        BigDecimal returnMoney = jiFenReturnConfig.getBigDecimal("returnMoney");
        benefit = DecimalUtil.addArray(returnMoney, benefit);
        tUserAccount.setBenefit(benefit);
        BenefitTransaction bt = new BenefitTransaction( userId,null,null,benefit,
                BenefitTranTypeDict.BENEFIT_TRAN_TYPE_1300.getCn(),returnMoney, "积分返现");
        addBenefitTransaction(bt);
        //返积分
        BigDecimal returnIntegral = jiFenReturnConfig.getBigDecimal("returnIntegral");
        BigDecimal integral = tUserAccount.getIntegral();
        integral = DecimalUtil.addArray(integral, returnIntegral);
        tUserAccount.setIntegral(integral);
        IntegralTransaction it = new IntegralTransaction();
        it.setCreateTime(new Date());
        it.setType(IntegralTranTypeDict.NTEGRAL_TRAN_TYPE_GOODS_400.getCn());
        it.setDes("积分消费返积分");
        it.setIntegral(returnIntegral);
        it.setUserId(userId);
        //变更后积分
        it.setAccountTotalIntegral(integral);
        addIntegralTransaction(it);
        tUserAccountMapper.updateById(tUserAccount);
        return integralReturn;
    }
}
